home *** CD-ROM | disk | FTP | other *** search
/ Gekikoh Dennoh Club 7 / Gekikoh Dennoh Club Vol. 7 (Japan).7z / Gekikoh Dennoh Club Vol. 7 (Japan) (Track 01).bin / games / otoko / source.lzh / FuncEnemy / oplinear.c < prev    next >
C/C++ Source or Header  |  1999-06-14  |  5KB  |  204 lines

  1. /* 開いて直線弾 */
  2. #include <xsp2lib.h>
  3.  
  4. #include "../otoko.h"
  5. #include "../player.h"
  6. #include "../enemy.h"
  7. #include "../eshot.h"
  8. #include "../effect.h"
  9. #include "../priority.h"
  10. #include "../sound.h"
  11. #include "../entry.h"
  12.  
  13. #define PALET_MAIN        0x0400
  14.  
  15. #define SPEED_1        8    /* 横移動の加速度 */
  16. #define SPEED_1N    18    /* 横移動の加速度を足す回数 */
  17. #define SPEED_2        12    /* 撤退時の加速度 */
  18. #define SPEED_2N    24    /* 撤退時の加速度を足す回数 */
  19.  
  20. #define SPEED_NRG    8    /* 敵弾の速度(遅い方) */
  21. #define SPEED_NRG2    16    /* 敵弾の速度(速い方) */
  22.  
  23. #define ENTRY_CONTROL_ADD    10    /* entry_control に足す値 */
  24.  
  25.  
  26. enum {
  27.     MOVETO_L = 0,
  28.     MOVETO_R,
  29. };
  30.  
  31. static short EnemyMoveOpLinear (ENEMY *);
  32. static void EnemyTiniOpLinear (ENEMY *);
  33.  
  34.  
  35. void EnemyInitOpLinear (ENEMY * p)
  36. {
  37.     p->vx = 0;
  38.     p->vy = 8 * 65536;
  39.     p->hit_px = 24;
  40.     p->hit_py = 16;
  41.     p->hit_sx = 24;
  42.     p->hit_sy = 16;
  43.     p->hit_cx = 6;
  44.     p->damage = p->damage_core = 0;
  45.     p->flash = 0;
  46.     p->hp = 240;
  47.     p->pt = obj_oplaser;
  48.     p->core_pt = sp_core01;
  49.     p->seq = 0;
  50.     p->func_enemy_move = EnemyMoveOpLinear;
  51.     p->func_enemy_tini = EnemyTiniOpLinear;
  52.     if (SHORT_LX < 128 + 16)
  53.         p->cwork = 0;
  54.     else
  55.         p->cwork = !0;
  56.  
  57.     entry_control += ENTRY_CONTROL_ADD;
  58. }
  59.  
  60.  
  61.  
  62. static short EnemyMoveOpLinear (ENEMY * p)
  63. {
  64.     /* 速度を足して上位ワード(固定整数部)だけ取り出す */
  65.     p->x = (p->lx += p->vx) >> 16;
  66.     p->y = (p->ly += p->vy) >> 16;
  67.  
  68.     switch (p->seq) {
  69.     case 0:
  70.         p->vy -= 16384;
  71.         if (p->vy < 0) {
  72.             p->seq++;
  73.             p->vy = 0;
  74.         }
  75.         break;
  76.     case 1:        /* 開く */
  77.         if (p->pt == obj_oplaser + 27)
  78.             SoundSetSE (SE_LOCK);    /* 「がちゃん」という効果音を鳴らす */
  79.         if (p->pt < obj_oplaser + 35) {
  80.             p->pt++;
  81.         } else {
  82.             p->seq++;
  83.             p->s_work = 0;
  84.             if (p->cwork == 0) {
  85.                 SubEnemyMoveToInit (p, SHORT_LX + 128, SHORT_LY - 16, SPEED_1, SPEED_1N);
  86.                 p->m_work = MOVETO_L;    /* 次の移動方向 */
  87.             } else {
  88.                 SubEnemyMoveToInit (p, SHORT_LX - 128, SHORT_LY - 16, SPEED_1, SPEED_1N);
  89.                 p->m_work = MOVETO_R;
  90.             }
  91.             p->m_work2 = 0;
  92.             p->m_work3 = 0;
  93.         }
  94.         break;
  95.     case 2:        /* 攻撃開始 */
  96.         if (SubEnemyMoveTo (p) < 0) {
  97.             short m_work_table[2] =
  98.             {MOVETO_R, MOVETO_L};
  99.             signed short dx_table[2] =
  100.             {-64, 64};
  101.             signed short dy_table[5] =
  102.             {-16, 8, 16, -24, 16};
  103.             p->m_work2++;
  104.             if (p->m_work2 > 8) {
  105.                 p->seq++;    /* 撤退 */
  106.                 SubEnemyMoveToInit (p, SHORT_LX, -64, SPEED_2, SPEED_2N);
  107.             } else {
  108.                 SubEnemyMoveToInit (p, SHORT_LX + dx_table[p->m_work], SHORT_LY + dy_table[p->m_work3], SPEED_1, SPEED_1N);
  109.                 p->m_work = m_work_table[p->m_work];    /* 次の移動方向 */
  110.                 p->m_work3++;
  111.                 if (p->m_work3 > 4)
  112.                     p->m_work3 = 0;
  113.             }
  114.         }
  115.         switch (p->s_work++) {
  116. #define    TIME_SHOT_INTERVAL    30    /* ショットを撃つ間隔 */
  117.         case 4 + TIME_SHOT_INTERVAL * 0:
  118.         case 4 + TIME_SHOT_INTERVAL * 1:
  119.         case 4 + TIME_SHOT_INTERVAL * 2:
  120.         case 4 + TIME_SHOT_INTERVAL * 3:
  121.             EshotInit (ESHOT_LASER01, SHORT_LX - 18, SHORT_LY + 24, SPEED_NRG, 64, 0);
  122.             EshotInit (ESHOT_LASER01, SHORT_LX + 18, SHORT_LY + 24, SPEED_NRG, 64, 0);
  123.             EshotInit (ESHOT_LASER01, SHORT_LX - 18, SHORT_LY + 24, SPEED_NRG2, 64, 0);
  124.             EshotInit (ESHOT_LASER01, SHORT_LX + 18, SHORT_LY + 24, SPEED_NRG2, 64, 0);
  125.             SoundSetSE (SE_LASER);
  126.             break;
  127.         case 4 + TIME_SHOT_INTERVAL * 5:
  128.             p->s_work = 0;
  129.             break;
  130.         default:
  131.             break;
  132.         }
  133.         break;
  134.  
  135.     case 3:        /* 撤退 */
  136.         if (SubEnemyMoveTo (p) < 0)
  137.             SubEnemyMoveToInit (p, SHORT_LX, -64, SPEED_2, SPEED_2N);
  138.         /* 画面外に出たら消去 */
  139.         if (SHORT_LY < -64)
  140.             return (-1);    /* 消去 */
  141.         break;
  142.     }
  143.  
  144.     /* 自機ショットに当たった時の処理 */
  145.     if (p->damage) {
  146.         if (p->damage_core) {
  147.             SoundSetSE (SE_CORE_DAMAGE);
  148.             p->info = PALET_RED | PRIORITY_BOSS;
  149.             p->damage_core = 0;
  150.         } else {
  151.             SoundSetSE (SE_DAMAGE);
  152.             p->info = PALET_DAMAGE | PRIORITY_BOSS;
  153.         }
  154.         if ((p->hp -= p->damage) <= 0) {
  155.             EffectInit (EFFECT_EXPL, 0, p->x, p->y);
  156.             SoundSetSE (SE_EXPL_M);    /* 中ボス爆発音 */
  157.             if ((p->core_info == (PALET_CORE_RED | PRIORITY_BOSS))
  158.                 || (p->core_info == (PALET_CORE_RED | PRIORITY_BOSS_CORE)))
  159.                 EffectInit (EFFECT_POINTS_RED, POINTS_2000, p->x, p->y);
  160.             else
  161.                 EffectInit (EFFECT_POINTS_BLUE, POINTS_1200, p->x, p->y);
  162.             if (disp_level == DISP_LEVEL_HIGH)
  163.                 EffectInit (EFFECT_HAHENMINI, 0, p->x, p->y);
  164.             return (-1);    /* 消去 */
  165.         }
  166.         p->damage = 0;
  167.         p->flash = TIMER_FLASH_DAMAGE;
  168.     } else {
  169.         if ((p->flash++ > TIMER_FLASH_RED) && (p->hp < 100)) {
  170.             p->info = PALET_RED | PRIORITY_BOSS;
  171.             if (p->flash > TIMER_FLASH_NORMAL)
  172.                 p->flash = 0;
  173.         } else {
  174.             p->info = PALET_MAIN | PRIORITY_BOSS;
  175.         }
  176.     }
  177.     xobj_set_st (p);
  178.  
  179.     /* コアの表示 */
  180.     {
  181.         short priority;
  182.  
  183.         if (p->pt > obj_oplaser + 30)
  184.             priority = PRIORITY_BOSS;
  185.         else
  186.             priority = PRIORITY_BOSS_CORE;
  187.         p->core_x = p->x - 8;    /* コアの中心は (-8,-8) ドットずれる */
  188.         p->core_y = p->y - 8;
  189.         if (player->y < p->y + 64)    /* 自機との座標の差が小さければ赤 */
  190.             p->core_info = PALET_CORE_RED | priority;
  191.         else
  192.             p->core_info = PALET_CORE_BLUE | priority;
  193.         xsp_set_st (&(p->core_x));
  194.     }
  195.     return (0);
  196. }
  197.  
  198.  
  199.  
  200. static void EnemyTiniOpLinear (ENEMY * p)
  201. {
  202.     entry_control -= ENTRY_CONTROL_ADD;
  203. }
  204.